package com.kla.power.controller;

import com.kla.power.config.LogPointer;
import com.kla.power.entity.InverterAmountStatisticsDayEntity;
import com.kla.power.entity.StationEntity;
import com.kla.power.entity.UserEntity;
import com.kla.power.mapper.InverterElectricMapper;
import com.kla.power.service.IInverterAmountStatisticsDayService;
import com.kla.power.service.IStationService;
import com.kla.power.util.CommonUtil;
import com.kla.power.util.ConstUtil;
import com.kla.power.util.RedisUtils;
import com.kla.power.util.ResultBody;
import com.kla.power.vo.PlanPowerVO;
import org.apache.commons.lang.StringUtils;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 前端控制器
 * </p>
 * @author WuZH
 * @since 2024-08-06
 */
@RestController
@RequestMapping ("screen")
@CrossOrigin (value = "*", maxAge = 3600)
public class ScreenController {

    @Resource
    private IStationService iStationService;
    @Resource
    private InverterElectricMapper inverterElectricMapper;
    @Resource
    private IInverterAmountStatisticsDayService iInverterAmountStatisticsDayService;


    /**
     * 第三个大屏
     * @param stationEntity
     * @return
     */
    @RequestMapping ("stationInfo")
    @LogPointer ("大屏：电站基本信息")
    public ResultBody stationInfo (@RequestBody StationEntity stationEntity) {
        UserEntity userEntity = (UserEntity) RedisUtils.get ( stationEntity.getToken () );
        stationEntity.setMerchantId ( userEntity.getMerchantId () );
        Map<String, Object> map = new HashMap<> ();
        // 求一个商户下所有电站所有逆变器实时发电数据
        // 设置inverter_system_info分区名称
        LocalDate localDate = LocalDate.now ();
        String yearAndMonth = localDate.getYear () + "" + ( localDate.getMonthValue () < 10 ? "0" + localDate.getMonthValue () : localDate.getMonthValue () );
        String partitionName = "partition (p" + yearAndMonth + ")";
        //stationEntity.setPartitionName ( partitionName );
        List<StationEntity> stationEntities = inverterElectricMapper.queryPowerGroupStation ( stationEntity );
        double dayPower = 0, totalPower = 0, allCapacity = 0;
        for ( StationEntity station : stationEntities ) {
            dayPower += Double.parseDouble ( StringUtils.isBlank ( station.getTodayEnergy () ) ? "0" : station.getTodayEnergy () );
            totalPower += Double.parseDouble ( StringUtils.isBlank ( station.getGridPower () ) ? "0" : station.getGridPower () );
            allCapacity += station.getPower ();
        }
        // 查询一个商户下所有电站所有逆变器的年度发电量
        Calendar calendar = Calendar.getInstance ();
        calendar.set ( Calendar.MONTH, 0 );//1月
        calendar.set ( Calendar.DAY_OF_MONTH, 1 );
        stationEntity.setStartTime ( calendar.getTime () );
        calendar.set ( Calendar.MONTH, 11 );//12月
        int actualMaximum = calendar.getActualMaximum ( Calendar.DATE );
        calendar.set ( Calendar.DAY_OF_MONTH, actualMaximum );
        stationEntity.setEndTime ( calendar.getTime () );
        List<InverterAmountStatisticsDayEntity> inverterAmountStatisticsDayEntities = iInverterAmountStatisticsDayService.queryAllStationAmountList ( stationEntity );
        double sum = inverterAmountStatisticsDayEntities.stream ().mapToDouble ( year -> Double.parseDouble ( year.getYesterdayPower () ) ).sum ();

        //求本月备份发电数据
        Calendar calendarByMonth = Calendar.getInstance ();
        calendarByMonth.set ( Calendar.DAY_OF_MONTH, 1 );//本月1号
        stationEntity.setStartTime ( calendarByMonth.getTime () );
        calendarByMonth.set ( Calendar.DAY_OF_MONTH, calendarByMonth.getActualMaximum ( Calendar.DAY_OF_MONTH ) );
        int lastDayOfMonth = calendarByMonth.get ( Calendar.DAY_OF_MONTH ); //本月最后一天
        calendarByMonth.set ( Calendar.DAY_OF_MONTH, lastDayOfMonth );
        stationEntity.setEndTime ( calendarByMonth.getTime () );
        List<InverterAmountStatisticsDayEntity> inverterAmountStatisticsDayEntitiesByMonth = iInverterAmountStatisticsDayService.queryAllStationAmountList ( stationEntity );
        double monthPower = inverterAmountStatisticsDayEntitiesByMonth.stream ().mapToDouble ( year -> Double.parseDouble ( year.getYesterdayPower () ) ).sum ();

        // 统计有效电站
        stationEntity.setType ( ConstUtil.STATION_MAIN_TYPE );
        List<StationEntity> stationCount = iStationService.stationDistribution ( stationEntity );
        map.put ( "stationCount", stationCount.size () );
        map.put ( "totalCapacity", CommonUtil.parseDecimalPoint ( allCapacity ) );
        map.put ( "totalActivePower", CommonUtil.parseDecimalPoint ( totalPower ) );
        map.put ( "totalDayPower", CommonUtil.parseDecimalPoint ( dayPower ) );
        map.put ( "totalMonthPower", CommonUtil.parseDecimalPoint ( monthPower + dayPower ) );
        map.put ( "totalYearPower", CommonUtil.parseDecimalPoint ( ( sum + dayPower ) ) );
        return ResultBody.success ( map );
    }


    /**
     * 查询电站数量和装机容量，按该商户所属不同城市分组
     * @return
     */
    @RequestMapping ("stationNum")
    @LogPointer ("大屏：电站数量和装机容量")
    public ResultBody stationNum (@RequestBody StationEntity stationEntity) {
        UserEntity userEntity = (UserEntity) RedisUtils.get ( stationEntity.getToken () );
        stationEntity.setMerchantId ( userEntity.getMerchantId () );
        List<Map<String, Integer>> maps = iStationService.screenStationNum ( stationEntity );
        return ResultBody.success ( maps );
    }


    /**
     * 加载计划发电量以及实际发电量，并显示完成率
     * @param stationEntity
     * @return
     */
    @RequestMapping ("planPowerData")
    @LogPointer ("计划发电量")
    public ResultBody planPowerData (@RequestBody StationEntity stationEntity) {
        List<PlanPowerVO> planPowerVOS = new ArrayList<> ();
        // 查询本商户所有电站的计划发电量，均分12个月
        UserEntity userEntity = (UserEntity) RedisUtils.get ( stationEntity.getToken () );
        stationEntity.setType ( ConstUtil.STATION_MAIN_TYPE );
        List<StationEntity> stationEntities = iStationService.stationDistribution ( stationEntity );
        double planPower = 0; // 总计划发电量
        for ( StationEntity entity : stationEntities ) {
            planPower += entity.getPlanPower () == null ? 0 : Double.parseDouble ( StringUtils.isBlank ( entity.getPlanPower () ) ? "0" : entity.getPlanPower () );
        }
        // 均分12个月
        for ( int i = 0; i < 12; i++ ) {
            PlanPowerVO planPowerVO = new PlanPowerVO ();
            planPowerVO.setMonth ( CommonUtil.getDateStrFormat ( new Date (), "yyyy" ) + "-" + CommonUtil.parseMonthByDecimal ( i + 1 ) );
            planPowerVO.setPlanPower ( CommonUtil.divided ( planPower, 12 ) );
            planPowerVO.setRealityPower ( "0" );
            planPowerVO.setRate ( "0" );
            planPowerVOS.add ( planPowerVO );
        }
        // 求商户下今天发电量之和
        stationEntity.setMerchantId ( userEntity.getMerchantId () );
        // 求该商户今天发电量之和
        // 设置inverter_system_info分区名称
        LocalDate localDate = LocalDate.now ();
        String yearAndMonth = localDate.getYear () + "" + ( localDate.getMonthValue () < 10 ? "0" + localDate.getMonthValue () : localDate.getMonthValue () );
        String partitionName = "partition (p" + yearAndMonth + ")";
        stationEntity.setPartitionName ( partitionName );
        List<StationEntity> toDayPower = inverterElectricMapper.queryPowerGroupStation ( stationEntity );
        double toDayTotal = toDayPower.stream ().mapToDouble ( toDay -> Double.parseDouble ( StringUtils.isBlank ( toDay.getTodayEnergy () ) ? "0" : toDay.getTodayEnergy () ) ).sum ();
        // 本商户下所有电站今年实际发电量，按月显示
        Calendar calendar = Calendar.getInstance ();
        calendar.set ( Calendar.MONTH, 0 );//1月
        calendar.set ( Calendar.DAY_OF_MONTH, 1 );
        stationEntity.setStartTime ( calendar.getTime () );
        calendar.set ( Calendar.MONTH, 11 );//12月
        int actualMaximum = calendar.getActualMaximum ( Calendar.DATE );
        calendar.set ( Calendar.DAY_OF_MONTH, actualMaximum );
        stationEntity.setEndTime ( calendar.getTime () );
        List<InverterAmountStatisticsDayEntity> inverterAmountStatisticsDayEntities = iInverterAmountStatisticsDayService.queryAllStationAmountList ( stationEntity );
        Map<String, List<InverterAmountStatisticsDayEntity>> collect = inverterAmountStatisticsDayEntities.stream ().collect ( Collectors.groupingBy ( InverterAmountStatisticsDayEntity :: getMonthTime ) );
        for ( Map.Entry<String, List<InverterAmountStatisticsDayEntity>> stringListEntry : collect.entrySet () ) {
            // 每个月的发电量之和
            double monthTotalPower = stringListEntry.getValue ().stream ().mapToDouble ( monthTotal -> Double.parseDouble ( monthTotal.getYesterdayPower () ) ).sum ();
            if ( CommonUtil.checkMonth ( stringListEntry.getKey () ) ) {
                monthTotalPower += toDayTotal; // 加上今天的
            }
            // value为按月的发电量集合，求发电量之和即每个月的实际发电量
            double finalMonthTotalPower = monthTotalPower;
            planPowerVOS.forEach ( planPowerVO -> {
                if ( planPowerVO.getMonth ().equals ( stringListEntry.getKey () ) ) {
                    planPowerVO.setRealityPower ( String.valueOf ( finalMonthTotalPower ) );
                    // 求完成率
                    double reality = Double.parseDouble ( planPowerVO.getRealityPower () == null ? "0" : planPowerVO.getRealityPower () ); // 实际
                    double plan = Double.parseDouble ( planPowerVO.getPlanPower () == null ? "0" : planPowerVO.getPlanPower () ); // 计划
                    if ( plan > 0.0 ) {
                        planPowerVO.setRate ( CommonUtil.parseDecimalPoint ( reality / plan * 100 ) );
                    }
                }
            } );
        }
        return ResultBody.success ( planPowerVOS );
    }


    /**
     * 第三个大屏，年度计划发电量
     * @param stationEntity
     * @return
     */
    @RequestMapping ("planPower")
    @LogPointer ("大屏本年度计划发电量")
    public ResultBody planPower (@RequestBody StationEntity stationEntity) {
        UserEntity userEntity = (UserEntity) RedisUtils.get ( stationEntity.getToken () );
        stationEntity.setType ( ConstUtil.STATION_MAIN_TYPE );
        stationEntity.setMerchantId ( userEntity.getMerchantId () );
        List<StationEntity> stationEntities = iStationService.stationDistribution ( stationEntity );
        double planPower = 0; // 总计划发电量
        for ( StationEntity entity : stationEntities ) {
            planPower += entity.getPlanPower () == null ? 0 : Double.parseDouble ( entity.getPlanPower () );
        }
        return ResultBody.success ( planPower );
    }

}
